package com.jason.sms.agent.component;

import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import com.jason.sms.agent.model.SmsMsg;
import com.jason.sms.agent.model.SmsRequest;
import com.jason.sms.agent.provider.SmsProvider;
import com.jason.sms.agent.provider.SmsProviderFactory;
import com.jason.sms.agent.queue.SmsQueue;
import com.jason.sms.agent.queue.SmsQueueImpl;
import com.jason.sms.agent.util.PhoneNumberType;
import com.jason.sms.agent.util.PhoneNumberUtil;

public class SmsComponent {
	
	private SmsProviderFactory providerFactory;
	
	private boolean running = true;
	
	private String numberSpace = ",";
	
	private SmsQueue smsQueue;
	
	private ExecutorService executor;
	
	private Worker worker;
	
	public SmsComponent(int poolSize){
		providerFactory = new SmsProviderFactory();
		smsQueue = new SmsQueueImpl();
		executor = Executors.newFixedThreadPool(poolSize);
	}
	
	/**
	 * 转换.
	 * @param msg
	 * @return
	 */
	public SmsRequest transSmsMsg(SmsMsg msg){
		SmsRequest request = new SmsRequest();
		request.setMsgId(msg.getMsgId());
		request.setContent(msg.getContent());
		request.setSendDate(msg.getSendDate());
		request.setSender(msg.getSender());
		request.setTitle(msg.getTitle());
		List<String> numbers = msg.getReceiver();
		for(String num:numbers){
			request.addDestNumber(PhoneNumberUtil.getPhoneType(num), num);
		}
		return request;
	}
	
	/**
	 * 分割.
	 * 
	 * @param request
	 * @return
	 */
	public List<SmsRequest> spiteRequest(SmsRequest request){
		Map<PhoneNumberType,List<String>> numbers = request.getDesNumber();
		List<SmsRequest> requests = new LinkedList<SmsRequest>();
		Iterator<PhoneNumberType> it = numbers.keySet().iterator();
		while(it.hasNext()){
			PhoneNumberType type = it.next();
			List<String> phoneNumbers = numbers.get(type);
			SmsRequest req = request.clone();
			req.setNumberType(type);
			req.setDesAddress(phoneNumbers);
			requests.add(req);
		}
		return requests;
	}
	
	public void addMsg(SmsMsg msg){
		smsQueue.addMsg(msg);
		Worker worker = new Worker();
		executor.submit(worker);
	}
	
	
	public void startWork(){
		if(worker == null){
			worker = new Worker();
			executor.submit(worker);
		}
	}
	
	class Worker implements Runnable{
		public void run(){
			while(running){
				SmsMsg msg = smsQueue.getMsg();
				if(msg != null){
					processMsg(msg);
				}
			}
		}
		
		public void processMsg(SmsMsg msg){
			SmsRequest request = transSmsMsg(msg);
			List<SmsRequest> reqs = spiteRequest(request);
			for(SmsRequest req:reqs){
				SmsProvider provider = providerFactory.getProvider(req);
				provider.sendSms(req);
			}
			
		}
	}

}
